package indi.yuluo.service.impl;

import indi.yuluo.dao.DiscussMapper;
import indi.yuluo.dao.DiscussionLikeMapper;
import indi.yuluo.entity.DTO.UserCommentsWithSignatureDto;
import indi.yuluo.entity.discussion.Discussion;
import indi.yuluo.entity.discussion.DiscussionLike;
import indi.yuluo.entity.user.UserInfo;
import indi.yuluo.service.DiscussService;
import indi.yuluo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: yuluo
 * @CreateTime: 2022-08-21  20:27
 * @Description: TODO
 */

@Service
@Slf4j
public class DiscussServiceImpl implements DiscussService {

    @Resource
    private DiscussMapper discussMapper;

    @Resource
    private UserService userService;

    @Resource
    private DiscussionLikeMapper discussionLikeMapper;

    @Override
    public Integer getDiscussNumByProblemId(String pid) {
        return discussMapper.getDiscussNumByProblemId(pid);
    }

    @Override
    public List<UserCommentsWithSignatureDto> getDiscussInfoByPId(Long pid) {

        List<Discussion> discussInfoByPId = discussMapper.getDiscussInfoByPId(pid);

        List<UserCommentsWithSignatureDto> list = discussInfoByPId.stream().map(item -> {
            UserCommentsWithSignatureDto userCommentsWithSignatureDto = new UserCommentsWithSignatureDto();

            BeanUtils.copyProperties(item, userCommentsWithSignatureDto);
            Long uid = item.getUid();

            UserInfo userInfo = userService.getUserById(uid);
            userCommentsWithSignatureDto.setSignature(userInfo.getSignature());
            userCommentsWithSignatureDto.setUsername(userInfo.getUsername());

            return userCommentsWithSignatureDto;
        }).collect(Collectors.toList());

        return list;
    }

    /**
     * 保存用户评论信息
     * @param currentProblemId
     * @param token
     * @param content
     * @return
     */
    @Override
    @Transactional(transactionManager = "transactionManager")
    @Rollback(value=false)
    // @Commit
    public boolean saveComments(Long currentProblemId, String token, String content) {

        boolean flag = false;

        // 获取用户的uuid
        UserInfo userByToken = userService.getUserByToken(token);

        Integer key = discussMapper.saveComments(userByToken.getUuid(), userByToken.getAvatar(), currentProblemId, content);

        if (Objects.nonNull(key)) {
            flag = true;
        }

        return flag;
    }

    /**
     * 用户点赞
     * 可以反复点击，已经点赞过了，再次点击取消，未点则加入
     * @param did
     * @param token
     * @return
     */
    @Override
    @Transactional(transactionManager = "transactionManager")
    @Rollback(value=false)
    public Map<Boolean, Integer>  like(Long did, String token) {

        boolean flag = false;

        UserInfo userByToken = userService.getUserByToken(token);
        Long uuid = userByToken.getUuid();

        List<DiscussionLike> discussionLikeList = discussionLikeMapper.getInfoByUserId(uuid);

        // 根据uid查出一个map，如果这个map value里面有此did，则证明点赞过，反之则没有
        Map<Long, Long> map = new HashMap<>();
        for (DiscussionLike discussionLike : discussionLikeList) {
            map.put(discussionLike.getId(), discussionLike.getDid());
        }

        // 遍历map的value找到和did对应的id
        boolean contains = map.containsValue(did);
        Long key = -1L;
        if (contains) {
            for (Map.Entry<Long, Long> entry: map.entrySet()) {
                if (entry.getValue().equals(did)) {
                    key = entry.getKey();
                }
            }
        }

        /*
        如果包含，取消点赞关系
        如果不包含，插入点赞关系
        返回取消或插入执行结果
         */
        Integer res;
        int resData;
        if (key != -1L) {
            res = discussionLikeMapper.deleteLikesStatus(key);
            // 讨论表中的点赞数-1
            discussMapper.updateLikesNumPlus1(did);
            resData = 1000;
        } else {
            res = discussionLikeMapper.insertLikesStatus(uuid, did);
            // 讨论表中的点赞数+1
            discussMapper.updateLikesNumMinus1(did);
            resData = 2000;
        }

        if (Objects.equals(res, 1)) {
            flag = true;
        }

        HashMap<Boolean, Integer> kvHashMap = new HashMap<>();
        kvHashMap.put(flag, resData);

        return kvHashMap;
    }

    /**查询用户点赞状态
     * @param did
     * @param token
     * @return
     */
    @Override
    public boolean checkLikesStatus(Long did, String token) {

        boolean flag = false;

        UserInfo userByToken = userService.getUserByToken(token);
        Long uuid = userByToken.getUuid();

        List<DiscussionLike> discussionLikeList = discussionLikeMapper.getInfoByUserId(uuid);

        for (DiscussionLike discussionLike : discussionLikeList) {
            if (Objects.equals(discussionLike.getDid(), did)){
                flag = true;
            }
        }

        return flag;
    }

    /**
     * 删除评论
     *
     * @param did
     * @param token
     * @return
     */
    @Override
    public int del(Long did, String token) {

        UserInfo userByToken = userService.getUserByToken(token);

        // 从评论表中查询用户和此评论的关系，是否此用户创建的
        Discussion discussion = this.getDiscussById(did);
        if (Objects.equals(discussion.getUid(), userByToken.getUuid())) {
            // 是此用户创建的，可以删除
            this.deleteById(did);

            // 同时删除评论点赞表中的点赞信息
            discussionLikeMapper.delBydId(did);

        } else {
            return 1000;
        }
        return 1;
    }

    /**
     * 根据id查询评论信息
     * @param did
     * @return
     */
    @Override
    public Discussion getDiscussById(Long did) {
        return discussMapper.selectById(did);
    }

    /**
     * 根据id删除评论信息
     * @param did
     */
    @Override
    public void deleteById(Long did) {
        discussMapper.deleteById(did);
    }
}
